/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package treegenerator.gui;

import com.jme3.gde.core.assets.ProjectAssetManager;
import com.jme3.renderer.RenderManager;
import com.jme3.util.JmeFormatter;
import java.awt.BorderLayout;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

/**
 *
 * @author jannes
 */
public class MainPanel extends JPanel{        
    private JLabel lblTitle;
    private TreeListPanel treeListPanel;
    private TreeXMLViewer xmlViewer;
    private TexturePanel texturePanel;    
    private TreePanel treePanel;        
    private File projectDir;
    private File currentFile;
    private ProjectAssetManager assetManager;
    private RenderManager renderManager;
    
    private void createPanel(){                  
        setLayout(new BorderLayout());
        
        lblTitle = new JLabel();
        Box hb = Box.createHorizontalBox();
        hb.add(Box.createHorizontalGlue());
        hb.add(lblTitle);
        hb.add(Box.createHorizontalGlue());
        add(hb, BorderLayout.NORTH);
        
        treeListPanel = new TreeListPanel(this);
        add(treeListPanel,BorderLayout.WEST);
                
        hb = Box.createHorizontalBox();
        add(hb,BorderLayout.CENTER);
        hb.add(new JSeparator(JSeparator.VERTICAL));
        xmlViewer = new TreeXMLViewer();
        hb.add(xmlViewer);        
        
        hb.add(new JSeparator(JSeparator.VERTICAL));
        texturePanel = new TexturePanel();        
        hb.add(texturePanel);        
        hb.add(new JSeparator(JSeparator.VERTICAL));                
                
        treePanel = new TreePanel(this,assetManager);
        add(treePanel,BorderLayout.EAST);                
    }       
    
    public void dispose(){
        treePanel.dispose();                                           
        texturePanel = null;
        xmlViewer = null;       
        projectDir = null;
    }
    
    public MainPanel(File projectDir, ProjectAssetManager assetManager, RenderManager renderManager){                
        this.projectDir = projectDir;
        this.assetManager = assetManager;  
        this.renderManager = renderManager;
        String settingsDir = System.getProperty("netbeans.user");
        File dir = new File(settingsDir);
        dir = new File(dir,"TreeData");                
        if(!dir.exists()){
            InputStream is = getClass().getClassLoader().getResourceAsStream("/treegenerator/examples/Trees.zip");
            unzip(is, dir);
        }
        JmeFormatter formatter = new JmeFormatter();

        Handler consoleHandler = new ConsoleHandler();
        consoleHandler.setFormatter(formatter);

        Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
        Logger.getLogger("").addHandler(consoleHandler);
        

        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
        createPanel();
                
    }                    
    
    public void loadTree(File file){
        try {                                       
            currentFile = file;
            File baseDir = file.getParentFile();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();      
            DocumentBuilder loader = factory.newDocumentBuilder();                 
            Document doc = loader.parse(file);             
            String treeName = file.getName().substring(0, file.getName().length()-4);            
            treePanel.setTreeName(treeName);
            File f = new File(baseDir, "ArbaroFiles/" + treeName + ".xml");                        
            if(xmlViewer.checkXML(f)){                           
                xmlViewer.readXML(f);
            }                            
            texturePanel.reset();
            lblTitle.setText(treeName);
            File textureBase = new File(baseDir,"Textures/" + treeName);                     
            File textureDir = new File(textureBase,"Trunk");            
            if(textureDir.exists() && textureDir.isDirectory()){
                File[] files = textureDir.listFiles();
                for(File fi: files){
                    texturePanel.addTrunkTile(fi);
                }
            }                        
            textureDir = new File(textureBase,"Stem");
            if(textureDir.exists() && textureDir.isDirectory()){
                File[] files = textureDir.listFiles();
                for(File fi: files){
                    texturePanel.addStemTile(fi);
                }
            }
            textureDir = new File(textureBase,"Leaf");
            if(textureDir.exists() && textureDir.isDirectory()){
                File[] files = textureDir.listFiles();
                for(File fi: files){
                    texturePanel.addLeafTile(fi);
                }
            }

            org.w3c.dom.Node n = doc.getElementsByTagName("trunkTextures").item(0);                        
            NodeList children = n.getChildNodes();
            for(int i = 0; i < children.getLength(); i++){
                org.w3c.dom.Node child = children.item(i);
                if(child.getNodeName().equals("horizontalTiles")){
                    texturePanel.setTrunkHorizontal(child.getTextContent());
                }else if(child.getNodeName().equals("verticalTiles")){
                    texturePanel.setTrunkVertical(child.getTextContent());
                }else if(child.getNodeName().equals("topTiles")){
                    texturePanel.setTrunkTop(child.getTextContent());
                }
            }
            n = doc.getElementsByTagName("stemTextures").item(0);
            children = n.getChildNodes();
            for(int i = 0; i < children.getLength(); i++){
                org.w3c.dom.Node child = children.item(i);
                if(child.getNodeName().equals("horizontalTiles")){
                    texturePanel.setStemHorizontal(child.getTextContent());
                }else if(child.getNodeName().equals("verticalTiles")){
                    texturePanel.setStemVertical(child.getTextContent());
                }else if(child.getNodeName().equals("topTiles")){
                    texturePanel.setStemTop(child.getTextContent());
                }
            }
            texturePanel.resetSeeds();
        }catch (Exception ex) {
            ex.printStackTrace();
        }   
    }              
    
    public void renameTree(String newName){
        String oldName = currentFile.getName().substring(0, currentFile.getName().length()-4);            
        File baseDir = currentFile.getParentFile();
        File f = new File(baseDir, oldName + ".xml");
        File newFile = new File(baseDir,newName + ".xml");
        f.renameTo(newFile);
        f = new File(baseDir,"ArbaroFiles/" + oldName + ".xml");
        f.renameTo(new File(baseDir, "ArbaroFiles/" + newName + ".xml"));
        f = new File(baseDir,"Textures/" + oldName );
        f.renameTo(new File(baseDir, "Textures/" + newName));
        treeListPanel.resetList();
        loadTree(newFile);
    }   
    
    public void removeTree(){
        String oldName = currentFile.getName().substring(0, currentFile.getName().length()-4);            
        File baseDir = currentFile.getParentFile();
        File f = new File(baseDir, oldName + ".xml");        
        f.delete();
        f = new File(baseDir,"ArbaroFiles/" + oldName + ".xml");
        f.delete();        
        f = new File(baseDir,"Textures/" + oldName );
        if(emptyDir(f)){
            f.delete();
        }        
        treeListPanel.resetList();
        texturePanel.reset();        
    }
    
    public TreeXMLViewer getXMLViewer(){
        return xmlViewer;
    }
    
    public TexturePanel getTexturePanel(){
        return texturePanel;
    }
    
    public File getProjectDirectory(){
        return projectDir;
    }
    
    public File getOpenedTree(){
        return currentFile;
    }
    
    public TreePanel getTreePanel(){
        return treePanel;
    }
    
    public TreeListPanel getTreeListPanel(){
        return treeListPanel;
    }
    
    public RenderManager getRenderManager(){
        return renderManager;
    }
 
    private boolean emptyDir(File dir){
        try{
            for(File f : dir.listFiles()){
                if(f.isDirectory()){
                    emptyDir(f);
                }else{
                    f.delete();
                }
            }
        }catch(Exception exc){}
        return dir.isDirectory() && dir.listFiles().length == 0;
    }
    
    public static void unzip(InputStream zipFile, File destFolder) {
        try {
            ZipInputStream zis = new ZipInputStream(zipFile);
            ZipEntry ze = null;
            while ((ze = zis.getNextEntry()) != null) {
                System.out.println("Unzipping " + ze.getName());
                if(ze.isDirectory()){
                    File f = new File(destFolder,ze.getName());
                    f.mkdirs();
                }else{
                    FileOutputStream fout = new FileOutputStream(new File(destFolder,ze.getName()));
                    for (int c = zis.read(); c != -1; c = zis.read()) {
                      fout.write(c);
                    }
                    zis.closeEntry();
                    fout.close();
                }
            }
            zis.close();
        }catch(Exception exc){
            JOptionPane.showMessageDialog(null, "error unzipping:" + exc);
        };
    }
    
    public void changeExportButton(File treeFile){
        treePanel.changeExportButton(treeFile);
    }
}
